package com.fengxing.ams.web.facade;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.apache.commons.io.FileUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jsoup.Jsoup;
import org.jsoup.helper.StringUtil;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.fengxing.ams.web.facade.intf.IParseFacade;
import com.fengxing.ams.web.facade.mouble.realtime.ISchool2DAO;
import com.fengxing.ams.web.facade.mouble.realtime.MajorVO2;
import com.fengxing.ams.web.facade.mouble.realtime.RealtimeStudentVO;
import com.fengxing.ams.web.facade.mouble.realtime.SchoolVO2;
import com.fengxing.ams.web.facade.mouble.task.ITaskDAO;
import com.fengxing.ams.web.facade.mouble.task.TaskVO;

@Service
@Transactional
public class ParseFacade implements IParseFacade {
	private static final Log logger = LogFactory.getLog(ParseFacade.class);
	private static File rootFile = new File(System.getProperty("java.io.tmpdir"));
	
	@Autowired
	ISchool2DAO school2DAO;
	@Autowired
	ITaskDAO taskDAO;
	
	@Override
	@Transactional(readOnly = false)
	public void parse(TaskVO taskVO) {
		File indexFile = new File(rootFile, "/" + taskVO.getId() + "/index.html");
		byte[] indexContent = getContent(indexFile, taskVO.getMedaData());
		if (indexContent == null) {
			logger.warn("index page download error!");
			return;
		}
		Document doc = null;
		try {
			doc = Jsoup.parse(new ByteArrayInputStream(indexContent), "gbk",
					"http://www.nm.zsks.cn/");
		} catch (IOException e) {
			logger.error("parser document error", e);
		}
		//校验document
		Elements tables = doc.select("table[id=report1]");
		if (tables == null || tables.isEmpty()) {
			logger.warn("index page has not tables!");
			return;
		}
		Element table = tables.first();
		//解析时间标签
		Element tdLabel = table.select("#report1 > tbody > tr:nth-child(1) > td.report1_1_2").first();
		String label = tdLabel.text();
		//解析各个科类
		Elements subjectAs = table.select("#report1 > tbody > tr > td.report1_2_2 > a");
		if (subjectAs == null || subjectAs.isEmpty()) {
			logger.warn("not found subject actions!");
			return;
		}
		for (Element subjectAction : subjectAs) {
			String subject = subjectAction.text();
			String subjectLocation = getLocation(subjectAction.attr("href"));
			//解析每个科类
			File sujectFile = new File(rootFile, "/" + taskVO.getId() + "/" + subject + ".html");
			byte[] subjectContent = getContent(sujectFile, subjectLocation);
			if (subjectContent == null) {
				logger.warn("subject page not found, subject=" + subject);
				continue;
			}
			try {
				doc = Jsoup.parse(new ByteArrayInputStream(subjectContent), "gbk",
						"http://www.nm.zsks.cn/");
				//解析subjectpage
				List<SchoolVO2> schools = parserSubjectInfo(taskVO, doc, subject);
				if (schools != null && !schools.isEmpty()) {
					batchInsert(schools);
				}
				this.taskDAO.updateStatus(taskVO.getId(), 2);
			} catch (IOException e) {
			}
		}
		//解析完成之后，将定时任务状态更新，将数据保存入库
		
	}
	
	@PersistenceContext
    protected EntityManager em;  
	
	@Transactional(readOnly = false)
    public void batchInsert(List list) {
    	
        for(int i = 0; i < list.size(); i++) {
            em.persist(list.get(i));
            if((i != 0 && i % 30== 0) || i == list.size() - 1) {
                em.flush();  
                em.clear();  
            }
        }  
    }
	
	private List<SchoolVO2> parserSubjectInfo(TaskVO task, Document doc, String subject) {
		Elements trs = doc.select("tr[style=height:22px;]");
		Elements headLine = doc.select("tr[style=height:32px;]").select("td");
		if (trs == null || trs.isEmpty()) {
			logger.warn("subject page has not any #report1 tbody tr, subject=" + subject);
			return null;
		}
		List<SchoolVO2> schools = new ArrayList<SchoolVO2> ();
		for (int i = 0; i < trs.size(); i++) {
			if (i == 0)
				continue;
			Element tr = trs.get(i);
			Elements tds = tr.select("td");
			SchoolVO2 schoolVO = parserCollege(task, tds, headLine);
			schoolVO.setClazz(subject);
			schools.add(schoolVO);
			parserMajor(task, schoolVO);
			if (schoolVO.getYibaorenshu() > 0)
				parserStudent(task, schoolVO, subject);
		}
		return schools;
	}

	private void parserStudent(TaskVO task, SchoolVO2 schoolVO, String subject) {
		File majorCacheFile = new File(rootFile, "/" + task.getId() + "/" + subject + "/" + schoolVO.getSchool_id() + "student.html");
		byte[] b = getContent(majorCacheFile, schoolVO.getStudent_href());
		List<RealtimeStudentVO> students = null;
		try {
			students = parserStudentVO(new ByteArrayInputStream(b), schoolVO);
		} catch (IOException e) {
		}
		schoolVO.setStudents(students);
	}
	
	@Transactional(readOnly = false)
	public void deleteRealtimeAll() {
		this.school2DAO.deleteAll();
	}
	
	private List<RealtimeStudentVO> parserStudentVO(InputStream input, SchoolVO2 school)
			throws IOException {
		Document doc = Jsoup.parse(input, "gbk",
				"http://www.nm.zsks.cn/zy_1_1_2015/");
		Elements trs = doc.select("tr");
		List<RealtimeStudentVO> vos = new ArrayList<RealtimeStudentVO>();
		for (int i = 0; i < trs.size(); i++) {
			Element tr = trs.get(i);
			Elements tds = tr.select("td");
			if (tds.size() == 0 || tds.size() < 11)
				continue;
			if (tds.get(0).text().equals("投档分 （含照顾分）"))
				continue;
			RealtimeStudentVO vo = new RealtimeStudentVO();
			int j = 0;
			List<String> major = new ArrayList<String> ();
			for (Element td : tds) {
				if (j == 0) {
					vo.setApply_score(Integer.valueOf(td.text()));
				} else if (j == 1) {
					vo.setTest_score(Integer.valueOf(td.text()));
				} else if (j == 2) {
					vo.setNation(td.text());
				} else if (j == 3) {
					vo.setGendar(td.text());
				} else if (j == 4) {
					if (!StringUtil.isBlank(td.text()))
						major.add(td.text());
				} else if (j == 5) {
					if (!StringUtil.isBlank(td.text()))
						major.add(td.text());
				} else if (j == 6) {
					if (!StringUtil.isBlank(td.text()))
						major.add(td.text());
				} else if (j == 7) {
					if (!StringUtil.isBlank(td.text()))
						major.add(td.text());
				} else if (j == 8) {
					if (!StringUtil.isBlank(td.text()))
						major.add(td.text());
				} else if (j == 9) {
					if (!StringUtil.isBlank(td.text()))
						major.add(td.text());
				} else if (j == 10) {
					if (td.text().equals("是")) {
						vo.setObey(true);
					} else {
						vo.setObey(false);
					}
				}
				j++;
			}
			vo.setClazz(school.getClazz());
			vo.setMajor(major);
			vo.setSchool(school);
			vos.add(vo);
		}
		return vos;
	}

	private List<MajorVO2> parserMajor(TaskVO task, SchoolVO2 schoolVO) {
		File majorCacheFile = new File(rootFile, "/" + task.getId() + "/" + schoolVO.getClazz() + "/" + schoolVO.getSchool_id() + ".html");
		Document doc = null;
		try {
			doc = Jsoup.parse(getContentInput(majorCacheFile, schoolVO.getSchool_href()), "gbk",
					"http://www.nm.zsks.cn/zy_1_1_2015/");
		} catch (IOException e) {
			e.printStackTrace();
		}
		Elements trs = doc.select("tr");
		List<MajorVO2> majors = new ArrayList<MajorVO2>();
		for (int i = 0; i < trs.size(); i++) {
			Element tr = trs.get(i);
			Elements tds = tr.select("td");
			if (tds.size() == 0 || tds.size() != 8)
				continue;
			if (tds.get(0).text().equals("专业代号"))
				continue;
			if (tds.get(6).text().equals("统计时间："))
				continue;
			MajorVO2 vo = new MajorVO2();
			int j = 0;
			for (Element td : tds) {
				if (j == 0) {
					vo.setMajor_id(td.text());
				} else if (j == 1) {
					vo.setMajor_name(td.text());
				} else if (j == 2) {
					vo.setPlan_num(Integer.valueOf(td.text()));
				} else if (j == 3) {
					vo.setYuji1bi1luquzuidifen(Integer.valueOf(td.text()));
				} else if (j == 4) {
					vo.setApply_num(Integer.valueOf(td.text()));
				} else if (j == 5) {
					vo.setXuefei(td.text());
				} else if (j == 6) {
					vo.setLocation(td.text());
				} else if (j == 7) {
					vo.setRemark(td.text());
				}
				j++;
			}
			vo.setSchoolVO2(schoolVO);
			majors.add(vo);
		}
		schoolVO.setMajors(majors);
		return majors;
		
	}

	private SchoolVO2 parserCollege(TaskVO task, Elements tds, Elements headLine) {
		if (tds.size() < 8)
			return null;
		SchoolVO2 vo = null;
		String school_id = null;
		String school_name = null;
		Integer plan_num = null;
		Integer yuji1bi1toudangzuidifen = null;
		String toudangbili = null;
		Integer yujitoudangzuidifen = null;
		Integer yingtoudangrenshu = null;
		Integer yibaorenshu = null;
		Integer quedangrenshu = null;
		String school_href = null;
		String student_href = null;
		for (int i = 0; i < headLine.size(); i++) {
			String head = headLine.get(i).text();
			Element td = tds.get(i);
			if (head.matches("院\\s?校\\s?代\\s?号\\s?")) {
				school_id = td.text();
			} else if (head.matches("院\\s?校\\s?名\\s?称\\s?")) {
				school_name = td.text();
				school_href = "http://www.nm.zsks.cn"
						+ td.getElementsByTag("a").get(0).attr("href");
			} else if (head.matches("计\\s?划\\s?数\\s?")) {
				plan_num = Integer.valueOf(td.text());
			} else if (head.indexOf("1:1") != -1) {
				yuji1bi1toudangzuidifen = Integer.valueOf(td.text());
			} else if (head.matches("投\\s?档\\s?比\\s?例\\s?")) {
				toudangbili = td.text();
			} else if (head.matches("预\\s?计\\s?投\\s?档\\s?最\\s?低\\s?分\\s?")) {
				yujitoudangzuidifen = Integer.valueOf(td.text());
			} else if (head.matches("应\\s?投\\s?档\\s?人\\s?数\\s?")) {
				yingtoudangrenshu = Integer.valueOf(td.text());
			} else if (head.matches("已\\s?报\\s?人\\s?数\\s?")) {
				yibaorenshu = Integer.valueOf(td.text());
				student_href = "http://www.nm.zsks.cn"
						+ td.getElementsByTag("a").get(0).attr("href");
			} else if (head.matches("缺\\s?档\\s?人\\s?数\\s?")) {
				if (!StringUtil.isBlank(td.text()))
					quedangrenshu = Integer.valueOf(td.text());
			}
		}
		vo = new SchoolVO2();
		vo.setPlan_num(plan_num);
		vo.setQuedangrenshu(quedangrenshu);
		vo.setSchool_href(school_href);
		vo.setSchool_id(school_id);
		vo.setSchool_name(school_name);
		vo.setStudent_href(student_href);
		vo.setToudangbili(toudangbili);
		vo.setYibaorenshu(yibaorenshu);
		vo.setYingtoudangrenshu(yingtoudangrenshu);
		vo.setYuji1bi1toudangzuidifen(yuji1bi1toudangzuidifen);
		vo.setYujitoudangzuidifen(yujitoudangzuidifen);
		return vo;
	}

	private String getLocation(String href) {
		return "http://www.nm.zsks.cn" + href;
	}
	
	public static void main(String[] args) {
		ParseFacade parser = new ParseFacade();
		TaskVO task = new TaskVO();
		task.setId(1);
		task.setMedaData("http://www.nm.zsks.cn/zy_3_1_2016/kl_10.html");
		parser.parse(task);
	}
	
	public byte[] getContent(File cacheFile, String url) {
		if (cacheFile.exists()) {
			try {
				return FileUtils.readFileToByteArray(cacheFile);
			} catch (IOException e) {
				logger.error("download document error", e);
			}
		}
		try {
			FileUtils.copyURLToFile(new URL(url), cacheFile);
			return FileUtils.readFileToByteArray(cacheFile);
		} catch (MalformedURLException e) {
			logger.error("download document error", e);
		} catch (IOException e) {
			logger.error("download document error", e);
		}
		return null;
	}
	
	public InputStream getContentInput(File cacheFile, String url) {
		byte[] d = null;
		if (cacheFile.exists()) {
			try {
				d = FileUtils.readFileToByteArray(cacheFile);
			} catch (IOException e) {
				logger.error("download document error", e);
			}
		}
		try {
			FileUtils.copyURLToFile(new URL(url), cacheFile);
			d = FileUtils.readFileToByteArray(cacheFile);
		} catch (MalformedURLException e) {
			logger.error("download document error", e);
		} catch (IOException e) {
			logger.error("download document error", e);
		}
		return new ByteArrayInputStream(d);
	}

}
